<template>
  <div class="node-box">
    <!-- 节点菜单 -->
    <Menu v-if="!graphData.onlyRead" :graphData="graphData" />
    <!-- 画布 -->
    <div ref="canvasContentRef" class="canvas-content">
      <Top :graphData="graphData" />
      <div
        v-loading="canvasLoading || userLoading"
        class="canvas-dom"
        :id="graphData.canvasId"
        :style="`height:${graphData.canvasHeight + 2}px;`"
      ></div>
    </div>
    <!-- 信息栏 -->
    <Info
      ref="InfoRef"
      :graphData="graphData"
      :userList="userList"
      :loading="submitLoading"
      @submit="submit"
    />
  </div>
</template>

<script setup>
import './register';
import Info from './components/Info';
import Menu from './components/Menu';
import Top from './components/Top';
import {
  initG6,
  saveCanvas,
  watchkeyDown,
  keyUpEvent,
  initSize,
  setActive,
  refreshUserNode
} from './common';
import { getAllRoleUser, getSite, updateSite } from '@/api/seats';
import { ElMessage } from 'element-plus';
const route = useRoute();

const graphData = reactive({
  canvasRoom: 'detail', // index首页 detail详情页
  canvasId: 'detailMountNode', // 画布id
  toolbarId: 'detailToolBar', // 工具栏id
  canvasWidth: 0, // 画布宽,
  canvasHeight: 0, // 画布高,
  graph: {}, // 实例
  onlyRead: true, // 是否只读
  activeNode: null, // 当前编辑的节点
  editForm: {}, // 正在编辑的表单
  router: useRouter(), // 路由
  changeInfoActive: () => {}, // 信息栏切换当前展开的内容
  canvasContentRef: {} // 动态设置宽高必须
});

// 宽高变化
const InfoRef = ref();
const canvasContentRef = ref();
function resizeFn() {
  initSize(graphData, true);
}

// 按键监听
function keyDownEvent(ev) {
  watchkeyDown(ev, graphData);
}

onMounted(() => {
  graphData.changeInfoActive = InfoRef.value.changeInfoActive;
  graphData.canvasContentRef = canvasContentRef;
  resizeFn();
  window.addEventListener('resize', resizeFn);
  window.addEventListener('keydown', keyDownEvent);
  window.addEventListener('keyup', keyUpEvent);
});
onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeFn);
  window.removeEventListener('keydown', keyDownEvent);
  window.removeEventListener('keyup', keyUpEvent);
  graphData.graph?.clear?.();
  graphData.graph?.destroy?.();
});
watch(route, val => {
  if (val.name !== 'CustomSeatsDetail') return;
  getInfo();
});

// 获取所有用户
const userLoading = ref(false);
const userList = ref([]);
async function getAllUser() {
  userLoading.value = true;
  try {
    const res = await getAllRoleUser();
    userList.value = res.data?.user_struct || [];
    if (!canvasLoading.value) initResData();
  } finally {
    userLoading.value = false;
  }
}
getAllUser();

// 获取画布信息
let parent_node_id;
let active_node_id = undefined;
let parseData = {};
const canvasLoading = ref(false);
async function getInfo() {
  parent_node_id = route.query?.parent_node_id;
  active_node_id = route.query?.active_node_id;
  canvasLoading.value = true;
  try {
    const res = await getSite({ office_id: parent_node_id });
    const nodes = res.data?.nodes || [];
    parseData = { nodes };
    if (!userLoading.value) initResData();
  } finally {
    canvasLoading.value = false;
  }
}
getInfo();

// 处理数据
function initResData() {
  refreshUserNode(parseData.nodes, userList.value);
  initCanvas();
}

// 初始化
let oldNodes = [];
let oldObjs = {};
async function initCanvas() {
  await nextTick();
  if (canvasLoading.value) return;
  initG6({ graphData, jsonData: JSON.stringify(parseData) });
  if (active_node_id) {
    setActive({ graphData, node: graphData.graph.findById(active_node_id) });
  }
  await nextTick();
  oldNodes = JSON.parse(saveCanvas(graphData))?.nodes || [];
  oldObjs = {};
  oldNodes.forEach(node => {
    oldObjs[node.id] = node;
  });
}

// 提交
const submitLoading = ref(false);
async function submit() {
  const jsonData = saveCanvas(graphData);
  const parseData = JSON.parse(jsonData);
  const nodes = parseData.nodes || [];
  const nodeObj = {};

  const add_nodes = [];
  const del_nodes = [];
  const update_nodes = [];

  nodes.forEach(node => {
    nodeObj[node.id] = node;
    const oldNode = oldObjs[node.id];
    if (oldNode) {
      if (JSON.stringify(node) !== JSON.stringify(oldNode)) {
        update_nodes.push(node);
      }
    } else {
      add_nodes.push(node);
    }
  });
  oldNodes.forEach(oldNode => {
    const newNode = nodeObj[oldNode.id];
    if (!newNode) {
      del_nodes.push(oldNode);
    }
  });
  const paramsData = {
    id: parent_node_id,
    add_nodes,
    del_nodes,
    update_nodes
  };
  submitLoading.value = true;
  try {
    await updateSite(paramsData);
    ElMessage.success('提交成功');
    getInfo();
  } finally {
    submitLoading.value = false;
  }
}
</script>

<style lang="scss" scoped>
@import './common.scss';
</style>
